require("plugin")

plugin.maps = {
	new = function(p)
		local self = { plugin = p, engines = {} }
		setmetatable(self, { __index = plugin.maps })
		self:registerEngines()
		self:setEngine(common.getConfig("plugin.maps.engine"))
		return self
	end,
	
	activate = function(self)
		self:showPage()
	end,
	
	setEngine = function(self, name)
		self.engine = self.engines[name]
		assert(self.engine, "Nonexistent map engine")
	end,
	
	registerEngines = function(self)
		local coord = common.getConfig("plugin.maps.default.coord")
		local scale = common.getConfig("plugin.maps.default.scale")
		self.engines["amapy.cz"] = {
			-- maps = { "basic", "ortho", "cyclo", "tourist" },
			maps = { "basic", "ortho" },
			defaultMap = "basic",
			render = function(self, f, width, height)
				f.r:doctype("html-transitional")
				f.r:beginl("html", { xmlns = "http://www.w3.org/1999/xhtml" })
				f.r:beginl("head")
				f.r:emptyl("meta", { ["http-equiv"] = "content-type", content = "text/html; charset=utf-8" })
				f:script("http://amapy.atlas.cz/api/api.ashx?guid=263816c3-2866-44cb-98da-b05a459d5c6e")
				f:script(nil, string.format([[
					var map
					var Page = {
						load: function() {
							map = new AMap("map");
							map.loadMaps(); 
							map.zoomTo(%g, new AGeoPoint(%q));
						}
					}
					
					window.addEvent('domready', Page.load.bind(Page));    
					
					function zoom(_in){
						if(_in){
							map.zoomIn();
						} else {
							map.zoomOut();
						}
					}
					
					function moveTo(coord){
						map.moveTo(new AGeoPoint(coord));
					}
					
					function setMap(type){
						var dn;
						switch(type){
						case 'basic':
							dn = A_NORMAL_MAP.displayName;
							break;
						case 'ortho':
							dn = A_PHOTO_MAP.displayName;
							break;
						case 'cyclo':
							dn = A_CYCLE_MAP.displayName;
							break;
						case 'tourist':
							dn = A_TOURISTIC_MAP.displayName;
							break;
						default:
							notify("Unknown map type: " + type);
							return;
						}
						map.setMapType(dn);
					}
				]], scale, coord))
				f.r:beginl("style")
				f.r:cssSheet({
					body = {
						font = "13px Verdana, 'Geneva CE', lucida, sans-serif;",
						margin = "0px",
						padding = "0px"
					}
				})
				f.r:endl("style")
				f.r:endl("head")
				f.r:beginl("body")
				f.r:htmlDiv(nil, {
					id = "map",
					style = {
						width = width .. "px",
						height = height .. "px"
					}
				})
				f.r:endl("body")
				f.r:endl("html")
			end
		}
		self.engines["google"] = {
			maps = { "normal", "satellite", "hybrid" },
			defaultMap = "normal",
			render = function(self, f, width, height)
				f.r:doctype("html-strict")
				f.r:beginl("html", { xmlns = "http://www.w3.org/1999/xhtml" })
				f.r:beginl("head")
				f.r:emptyl("meta", { ["http-equiv"] = "content-type", content = "text/html; charset=utf-8" })
				f:script("http://maps.google.com/maps?file=api&v=2&hl=en")
				local coords = coord:split(",")
				local lat = tonumber(coords[1])
				local lon = tonumber(coords[2])
				f:script(nil, string.format([[
					function initialize() {
						if (GBrowserIsCompatible()) {
							map = new GMap2(document.getElementById("map_canvas"));
							map.setCenter(new GLatLng(%g, %g), %d);
						}
					}
					function zoom(_in){
						if(_in){
							map.zoomIn();
						} else {
							map.zoomOut();
						}
					}
					function moveTo(coord){
						var a = coord.split(',');
						var lat = parseFloat(a[0]);
						var lon = parseFloat(a[1]);
						map.setCenter(new GLatLng(lat, lon), 10);
					}
					function setMap(type){
						var mt;
						switch(type){
						case 'normal':
							mt = G_NORMAL_MAP;
							break;
						case 'satellite':
							mt = G_SATELLITE_MAP;
							break;
						case 'hybrid':
							mt = G_HYBRID_MAP;
							break;
						default:
							notify("Unknown map type: " + type);
							return;
						}
						map.setMapType(mt);
					}
				]], lat, lon, scale))
				f.r:endl("head")
				f.r:beginl("body", { onload = "initialize()", onunload = "GUnload()", style = { margin = "0px" } })
				f.r:beginl("div", { id = "map_canvas", style = { width = width .. "px", height = height .. "px" } })
				f.r:endl("div")
				f.r:endl("body")
				f.r:endl("html")
			end
		}
	end,
	
	showPage = function(self)
		local f = form.new("maps", "html")
		local width, height = self.plugin.stoicheia:getScreenSize()
		self.engine.render(self, f, width, height)
		f:close()
		self.plugin.stoicheia:open(f.path)
		local defaultMapIndex = 0
		for n, v in pairs(self.engine.maps) do
			if v == self.engine.defaultMap then defaultMapIndex = n end
		end
		local followDefaultMapIndex = (defaultMapIndex % #(self.engine.maps)) + 1
		self:setControls(self.engine.maps[followDefaultMapIndex])
	end,
	
	setControls = function(self, maptype)
		self.plugin.stoicheia:setControls(false, "back", "zoomin", "zoomout", "map_" .. maptype)
	end,
	
	zoom = function(self, _in)
		assert(type(_in) == "boolean")
		self.plugin.stoicheia.gui.pagewin:exec(string.format("zoom(%s);", tostring(_in)))
	end,
	
	moveTo = function(self, coord)
		self.plugin.stoicheia.gui.pagewin:exec(string.format("moveTo(%q);", coord))
	end,
	
	setMap = function(self, _type)
		self.plugin.stoicheia.gui.pagewin:exec(string.format("setMap(%q);", _type))
	end,
	
	controlEvent = function(self, event)
		if event == "back" then
			self.plugin.stoicheia:showStartPage()
			return
		end
		if event == "zoomin" then
			self:zoom(true)
			return
		end
		if event == "zoomout" then
			self:zoom(false)
			return
		end
		if event:startsWith("map_") then
			self:changeMap(event:sub(5))
			return
		end
		log("plugin.maps", "Unknown control event: %s", event)
	end,
	
	pageEvent = function(self, event, arg)
		log("plugin.maps", "Unknown page event: %s - %s", event, arg)
	end,
	
	changeMap = function(self, map)
		local index
		for i, m in ipairs(self.engine.maps) do
			if m == map then
				index = i
			end
		end
		assert(type(index) == "number")
		local nextIndex = (index % #(self.engine.maps)) + 1
		local nextMap = self.engine.maps[nextIndex]
		self:setControls(nextMap)
		self:setMap(map)
	end
}


